
 
import java.io.*; 
public class ZiWang2{
 public static void main(String [] args)throws IOException{
  String ip; //用于接收IP 
  String mask;//用于接收子网掩码
  int ai1=0; 
  int ai2=0; 
  int ai3=0; 
  int bi1=0; 
  int bi2=0; 
  int ci=0; 
  int b_i=0; 
  int a_i1=0; 
  int a_i2=0; 
  int a_i3=0; 
  System.out.println("---------------划分子网---------------"); //输入要划分的IP地址:ip 
  System.out.println("请输入网络地址(格式为：x1.x2.x3.x4)："); 
  System.out.print("→:"); 
  InputStreamReader isr = new InputStreamReader(System.in); 
  BufferedReader br = new BufferedReader(isr); 
  ip = br.readLine(); 
  if(ip.indexOf(".") == -1){ //得到‘.’字符所在的位置，-1表示不存在
   System.out.println("输入错误，请使用‘.’作为分隔符，请检查输入！"); 
   return; 
  }
  //截取x1 
  int index1 = ip.indexOf('.'); //得到‘.’字符所在的位置
  String st1 = ip.substring(0,index1); //得到从0开始到index1结束的内容，即(0~index1-1)
  int x1=Integer.parseInt(st1);//把String类型的st转化成int型 
  //截取x2 
  int index2= ip.indexOf('.',index1+1); //ip.indexOf('.',index1+1)表示从index1+1的位置开始寻找字符‘.’。
  String st2 = ip.substring(index1+1,index2); //得到从index1+1开始到index2结束的内容，即(index1+1~index2-1)
  int x2=Integer.parseInt(st2);//把String类型的st转化成int型 
  //截取x3 
  int index3= ip.indexOf('.',index2+1); //ip.indexOf('.',index2+1)表示从index2+1的位置开始寻找字符‘.’。
  String st3 = ip.substring(index2+1,index3); //得到从index2+1开始到index3结束的内容，即(index2+1~index3-1)
  int x3=Integer.parseInt(st3);//把String类型的st转化成int型
  //截取x4 
  String st4 = ip.substring(index3+1,ip.length()); //得到从index3+1开始到字符串结束的内容，即(index3+1~ip.length())
  int x4=Integer.parseInt(st4);//把String类型的st转化成int型
  //判断IP是否合法

  if(x1<=0 || x2<0 ||x3<0||x4<0||x1>223||x2>255||x3>255||x4>255){
   System.out.println("ip地址输入错误，请检查输入！");
   return;
  }


  System.out.println("请输入子网掩码(格式为：m1.m2.m3.m4)："); 
  System.out.print("→:"); 
  mask = br.readLine(); 
  //判断子网掩码分隔符 
  if(mask.indexOf(".") == -1){ //得到‘.’字符所在的位置，-1表示不存在
   System.out.println("子网掩码输入错误，请使用‘.’作为分隔符，请检查输入！");
   return; 
  }
  if(!isMask(mask)){
   System.out.println("子网掩码输入错误，请检查输入！");
   return;
  }
  //截取m1
  int index_m1 = mask.indexOf('.'); //得到‘.’字符所在的位置
  String mst1 = mask.substring(0,index_m1); //得到从0开始到index_m1结束的内容，即(0~index_m1-1)
  int m1=Integer.parseInt(mst1);//把String类型的st转化成int型 
  //截取m2 
  int index_m2= mask.indexOf('.',index_m1+1); //mask.indexOf('.',index_m1+1)表示从index_m1+1的位置开始寻找字符‘.’。
  String mst2 = mask.substring(index_m1+1,index_m2); //得到从index_m1+1开始到index_m2结束的内容，即(index_m1+1~index_m2-1)
  int m2=Integer.parseInt(mst2);//把String类型的st转化成int型 
  //截取m3 
  int index_m3= mask.indexOf('.',index_m2+1); //mask.indexOf('.',index_m2+1)表示从index_m2+1的位置开始寻找字符‘.’。
  String mst3 = mask.substring(index_m2+1,index_m3); //得到从index_m2+1开始到index_m3结束的内容，即(index_m2+1~index_m3-1)
  int m3=Integer.parseInt(mst3);//把String类型的st转化成int型 
  //截取m4 
  String mst4 = mask.substring(index_m3+1,mask.length()); //得到从index_m3+1开始到字符串结束的内容，即(index_m3+1~mask.length())
  int m4=Integer.parseInt(mst4);//把String类型的st转化成int型

  //判断子网掩码是否合法


 // System.out.println(m1+" "+m2+" "+m3+" "+m4);





  //判断A、B、C类 
  //A类 
  if(x1>0&&x1<=126){ 
   System.out.println("本IP地址为:A类 "); 
   int ab_m2=Integer.parseInt(Integer.toBinaryString(m2)); //将m2从十进制转化成2进制并且转化成整形
   int ab_m3=Integer.parseInt(Integer.toBinaryString(m3)); //将m3从十进制转化成2进制并且转化成整形
   int ab_m4=Integer.parseInt(Integer.toBinaryString(m4)); //将m4从十进制转化成2进制并且转化成整形
   
   
   
   //A类情况下
   //子网掩码是255.x.0.0类型
   	if(m2!=255){ //地址掩码第二位小于255的情况
   		String a1_zhujiwei=String.valueOf(11111111-ab_m2); //String.valueOf(11111111-ab_m2)表示将二进制运算的结果装化成字符串
   		int a1_zhujiweishu=a1_zhujiwei.length()+16;//主机位数 
   		int a1_ziwangweishu=24-a1_zhujiweishu;//子网位数
   		double a1_ziwangshu=Math.pow(2,a1_ziwangweishu);//子网数,Math.pow(2,a1_ziwangweishu)表示幂次计算,即(2^(a1_ziwangweishu))
   		System.out.println("子网数为: "+a1_ziwangshu); 
   		System.out.println(""); 
   		double a1_zhujishu=Math.pow(2, a1_zhujiweishu)-2;//每个子网的主机数,Math.pow(2,a1_ziwangweishu)表示幂次计算,即(2^(a1_ziwangweishu))
   		System.out.println("每个子网的主机数为: "+a1_zhujishu); 
   		System.out.println(""); 
   		int a1_ziwangzengliang=256-m2;//子网增量 
   		while(ai1<=m2){ //地址掩码第二位小于255的情况，循环m2%a1_ziwangzengliang+1c次
    	
   			System.out.println("有效子网："+st1+"."+ai1+"."+st3+"."+st4); //有效子网 
     
    
   			System.out.println("广播地址："+st1+"."+(ai1+a1_ziwangzengliang-1)+"."+255+"."+255);//每个子网的广播地址 
   			System.out.println("IP范围  ："+st1+"."+ai1+"."+0+"."+1+"~"+st1+"."+(ai1+a1_ziwangzengliang-1)+"."+255+"."+254);//IP范围 
   			System.out.println("");  
     
   			ai1=ai1+a1_ziwangzengliang; 
   		} 
   }



    //A类情况下
    //子网掩码是255.255.x.0类型
   	else if(m2==255&&m3!=255 ){ 
    String a2_zhujiwei=String.valueOf(11111111-ab_m3); //String.valueOf(11111111-ab_m3)表示将二进制运算的结果装化成字符串
    int a2_zhujiweishu=a2_zhujiwei.length()+8;//主机位数 
    int a2_ziwangweishu=24-a2_zhujiweishu;//子网位数
    double a2_ziwangshu=Math.pow(2,a2_ziwangweishu);//子网数,Math.pow(2,a2_ziwangweishu)表示幂次计算,即(2^(a2_ziwangweishu))
    System.out.println("子网数为: "+a2_ziwangshu); 
    System.out.println(""); 
    double a2_zhujishu=Math.pow(2, a2_zhujiweishu)-2;//每个子网的主机数,Math.pow(2,a2_ziwangweishu)表示幂次计算,即(2^(a2_ziwangweishu))
    System.out.println("每个子网的主机数为: "+a2_zhujishu); 
    System.out.println(""); 
    int a2_ziwangzengliang=256-m3;//子网增量 
    while(a_i1<256){ 
     ai2=0; 
     while(ai2<=m3){ 
      System.out.println("有效子网："+st1+"."+a_i1+"."+ai2+"."+st4); //有效子网 
      
         System.out.println("广播地址："+st1+"."+a_i1+"."+(ai2+a2_ziwangzengliang-1)+"."+255);//每个子网的广播地址 
         System.out.println("IP范围  ："+st1+"."+a_i1+"."+ai2+"."+1+"~"+st1+"."+a_i1+"."+(ai2+a2_ziwangzengliang-1)+"."+254);//IP范围 
         System.out.println(""); 
        
     ai2=ai2+a2_ziwangzengliang; 
     } 
     a_i1++; 
    } 
   }





    //A类情况下
   	//子网掩码是255.255.255.x类型
   	else{ 
    String a3_zhujiwei=String.valueOf(11111111-ab_m4); //String.valueOf(11111111-ab_m4)表示将二进制运算的结果装化成字符串
    int a3_zhujiweishu=a3_zhujiwei.length();//主机位数 
    int a3_ziwangweishu=24-a3_zhujiweishu;//子网位数
    double a3_ziwangshu=Math.pow(2,a3_ziwangweishu);//子网数,Math.pow(2,a3_ziwangweishu)表示幂次计算,即(2^(a3_ziwangweishu))
    System.out.println("子网数为: "+a3_ziwangshu); 
    System.out.println(""); 
    double a3_zhujishu=Math.pow(2, a3_zhujiweishu)-2;//每个子网的主机数,Math.pow(2,a3_ziwangweishu)表示幂次计算,即(2^(a3_ziwangweishu))
    System.out.println("每个子网的主机数为: "+a3_zhujishu); 
    System.out.println(""); 
    int a3_ziwangzengliang=256-m4;//子网增量 
    while(a_i2<256){ 
     a_i3=0; 
     while(a_i3<256){ 
      ai3=0; 
      while(ai3<=m4){ 
       System.out.println("有效子网："+st1+"."+a_i2+"."+a_i3+"."+ai3); //有效子网 
       System.out.println("广播地址："+st1+"."+a_i2+"."+a_i3+"."+(ai3+a3_ziwangzengliang-1));//每个子网的广播地址 
       System.out.println("IP范围  ："+st1+"."+a_i2+"."+a_i3+"."+(ai3+1)+"~"+st1+"."+a_i2+"."+a_i3+"."+(ai3+a3_ziwangzengliang-2));//IP范围 
       System.out.println(""); 
       ai3=ai3+a3_ziwangzengliang; 
      } 
      a_i3++; 
     } 
     a_i2++;  
    } 
   } 
  } 
  
  
  
  
  //B类 
  if(x1>=128&&x1<=191){ 
   System.out.println("本IP地址为:B类 "); 
   System.out.println(""); 
   int bb_m4=Integer.parseInt(Integer.toBinaryString(m4));//将m4从十进制转化成2进制并且转化成整形 
   int bb_m3=Integer.parseInt(Integer.toBinaryString(m3));//将m3从十进制转化成2进制并且转化成整形 



   //B类情况下
   //子网掩码是255.255.x.0类型
   if(m3!=255){ 
    String b1_zhujiwei=String.valueOf(11111111-bb_m3);//String.valueOf(11111111-bb_m3)表示将二进制运算的结果装化成字符串
    int b1_zhujiweishu=b1_zhujiwei.length()+8;//主机位数 
    int b1_ziwangweishu=16-b1_zhujiweishu;//子网位数
    double b1_ziwangshu=Math.pow(2,b1_ziwangweishu);//子网数,Math.pow(2,b1_ziwangweishu)表示幂次计算,即(2^(b1_ziwangweishu)) 
    System.out.println("子网数为: "+b1_ziwangshu); 
    System.out.println(""); 
    double b1_zhujishu=Math.pow(2, b1_zhujiweishu)-2;//每个子网的主机数,Math.pow(2,b1_ziwangweishu)表示幂次计算,即(2^(b1_ziwangweishu)) 
    System.out.println("每个子网的主机数为: "+b1_zhujishu); 
    System.out.println(""); 
    int b1_ziwangzengliang=256-m3;//子网增量 
 
    while(bi1<=m3){      //255.255.128.0类似                 
     System.out.println("有效子网："+st1+"."+st2+"."+bi1+"."+st4); //有效子网 
        System.out.println("广播地址："+st1+"."+st2+"."+(bi1+b1_ziwangzengliang-1)+"."+255);//每个子网的广播地址 
              System.out.println("IP范围  ："+st1+"."+st2+"."+bi1+"."+1+"~"+st1+"."+st2+"."+(bi1+b1_ziwangzengliang-1)+"."+254);//IP范围 
              System.out.println(""); 
           bi1=bi1+b1_ziwangzengliang; 
    } 
   }



   //B类情况下
   //子网掩码是255.255.255.x类型
   else{
    String b2_zhujiwei=String.valueOf(11111111-bb_m4);//String.valueOf(11111111-bb_m4)表示将二进制运算的结果装化成字符串
    int b2_zhujiweishu=b2_zhujiwei.length();//主机位数 
    int b2_ziwangweishu=16-b2_zhujiweishu;//子网位数
    double b2_ziwangshu=Math.pow(2,b2_ziwangweishu);//子网数,Math.pow(2,b2_ziwangweishu)表示幂次计算,即(2^(b2_ziwangweishu)) 
    System.out.println("子网数为: "+b2_ziwangshu); 
    System.out.println(""); 
    double b2_zhujishu=Math.pow(2, b2_zhujiweishu)-2;//每个子网的主机数,Math.pow(2,b2_ziwangweishu)表示幂次计算,即(2^(b2_ziwangweishu)) 
    System.out.println("每个子网的主机数为: "+b2_zhujishu); 
    System.out.println(""); 
    int b2_ziwangzengliang=256-m4;//子网增量 
    while(b_i<256){ 
     bi2=0; 
     while(bi2<=m4){                          
      System.out.println("有效子网："+st1+"."+st2+"."+b_i+"."+bi2); //有效子网 
      System.out.println("广播地址："+st1+"."+st2+"."+b_i+"."+(bi2+b2_ziwangzengliang-1));//每个子网的广播地址 
      System.out.println("IP范围  ："+st1+"."+st2+"."+b_i+"."+(bi2+1)+"~"+st1+"."+st2+"."+b_i+"."+(bi2+b2_ziwangzengliang-2));//IP范围 
      System.out.println(""); 
      bi2=bi2+b2_ziwangzengliang; 
        } 
     b_i++; 
    } 
   } 
  }


  //C类 
  if(x1>=192&&x1<=223){ 
   System.out.println("本IP地址为:C类 "); 
   System.out.println(""); 
   int cb_m4=Integer.parseInt(Integer.toBinaryString(m4));//将m4从十进制转化成2进制并且转化成整形 
   String c_zhujiwei=String.valueOf(11111111-cb_m4);//String.valueOf(11111111-cb_m4)表示将二进制运算的结果装化成字符串 
   int c_zhujiweishu=c_zhujiwei.length();//主机位数 
   int c_ziwangweishu=8-c_zhujiweishu;//子网位数 
   double c_ziwangshu=Math.pow(2,c_ziwangweishu);//子网数,Math.pow(2,c_ziwangweishu)表示幂次计算,即(2^(c_ziwangweishu)) 
   System.out.println("子网数为: "+c_ziwangshu); 
   System.out.println(""); 
   double c_zhujishu=Math.pow(2, c_zhujiweishu)-2;//每个子网的主机数,Math.pow(2,c_ziwangweishu)表示幂次计算,即(2^(c_ziwangweishu)) 
   System.out.println("每个子网的主机数为: "+c_zhujishu); 
   System.out.println(""); 
   int c_ziwangzengliang=256-m4;//子网增量 
   while(ci<=m4){                          
    System.out.println("有效子网："+st1+"."+st2+"."+st3+"."+ci); //有效子网 
    System.out.println("广播地址："+st1+"."+st2+"."+st3+"."+(ci+c_ziwangzengliang-1));//每个子网的广播地址 
    System.out.println("IP范围  ："+st1+"."+st2+"."+st3+"."+(ci+1)+"~"+st1+"."+st2+"."+st3+"."+(ci+c_ziwangzengliang-2));//IP范围 
    System.out.println(""); 
    ci=ci+c_ziwangzengliang; 
   } 
  }
 }
 public static boolean isMask(String mask){
  String[] split = mask.split("\\.");
  StringBuilder sb = new StringBuilder();
  for (String s : split) {
   if(s.trim().equals("")){
    return false;
   }
   int i = Integer.parseInt(s);
   //如果有数字大于255，则直接返回false
   if (i > 255) {
    return false;
   }
   String binary = Integer.toBinaryString(i);
   //如果长度小于8，则在前面补0
   while (binary.length() < 8) {
    binary = "0".concat(binary);
   }
   sb.append(binary);
  }
  //32位二进制数中需要同时存在0和1，且不存在01
  return sb.toString().contains("1") && sb.toString().contains("0") && !sb.toString().contains("01");
 }

}
